<template>
  <div class="image-annotator">
    <!-- Header -->
    <div class="tool-head">
      <div class="tool-muster">
        <div class="logo-group">
          <div class="logo"></div>
          <div class="logo-title">ImageLabel</div>
        </div>
        <div class="select-operation">
          <div class="page-control">
            <div class="page-prev page-switch" title="Previous" @click="previousImage"></div>
            <div class="page-info">
              <p class="page-name" :title="currentImage.name">{{ currentImage.name || 'No Image' }}</p>
              <p class="name-process">
                <span class="process-index">{{ currentImageIndex + 1 }}</span> / 
                <span class="process-sum">{{ imageList.length }}</span>
              </p>
            </div>
            <div class="page-next page-switch" title="Next" @click="nextImage"></div>
          </div>
        </div>
        <div class="assist-tool">
          <div class="general-features">
            <p class="feature-list cross-line" title="Crosshair Toggle">
              <input 
                v-model="showCrosshair" 
                class="mui-switch mui-switch-anim" 
                type="checkbox"
                @change="toggleCrosshair"
              >
              <span>Crosshair</span>
            </p>
            <p class="feature-list label-shower focus" title="Annotation Display Toggle">
              <input 
                v-model="showAnnotations" 
                class="mui-switch mui-switch-anim" 
                type="checkbox"
                @change="toggleAnnotations"
              >
              <span>Annotations</span>
            </p>
            <p class="feature-list screen-shot" title="Screenshot" @click="takeScreenshot">
              <i class="bg"></i>
              <span>Screenshot</span>
            </p>
            <p class="feature-list screen-full" title="Fullscreen Toggle" @click="toggleFullscreen">
              <i class="bg"></i>
              <span>Fullscreen</span>
            </p>
          </div>
        </div>
      </div>
    </div>

    <div class="canvas-main">
      <!-- Tool Features -->
      <div class="tool-features">
        <div class="assist-features">
          <p class="open-folder" title="Open Folder" @click="openFolder"></p>
          <p class="save-json" title="Export JSON" @click="exportJson"></p>
          <input 
            ref="fileInput"
            class="open-folder-input" 
            type="file" 
            multiple 
            accept="image/*"
            @change="handleFileChange" 
            hidden
          >
        </div>
        <div class="separator"></div>
        <div class="tools">
          <div 
            class="tool-set tool-drag"
            :class="{ focus: currentTool === 'drag' }"
            title="Image Drag"
            @click="setTool('drag')"
          ></div>
          <div 
            class="tool-set tool-tags-manager"
            @click="showLabelManager = true"
          >
            <span class="icon-tags"></span>
          </div>
          <div 
            class="tool-set tool-rect"
            :class="{ focus: currentTool === 'rect' }"
            title="Rectangle Tool"
            @click="setTool('rect')"
          ></div>
          <div 
            class="tool-set tool-polygon"
            :class="{ focus: currentTool === 'polygon' }"
            title="Polygon Tool"
            @click="setTool('polygon')"
          ></div>
        </div>
        <div class="version">v2.0.0</div>
      </div>

      <!-- Canvas Content -->
      <div class="canvas-content">
        <canvas 
          ref="canvas"
          id="canvas"
          @mousedown="canvasMouseDown"
          @mousemove="canvasMouseMove"
          @mouseup="canvasMouseUp"
          @wheel="canvasWheel"
        ></canvas>
        <div class="scale-box">
          <div class="scale-canvas"></div>
          <div class="scale-panel">{{ Math.round(scale * 100) }}%</div>
        </div>
      </div>

      <!-- Results Panel -->
      <div class="comment-result">
        <div class="result-area">
          <p class="title">Annotations ({{ annotations.length }})</p>
          <div class="result-list-head">
            <div class="head-children">
              <p class="head-name">Name</p>
              <p class="head-edit">Edit</p>
              <p class="head-delete">Delete</p>
              <p class="head-display">Show/Hide</p>
            </div>
          </div>
          <div class="result-group">
            <div 
              v-for="(annotation, index) in annotations" 
              :key="index"
              class="result-item"
            >
              <span class="result-name">{{ annotation.label }}</span>
              <button class="result-edit" @click="editAnnotation(index)">Edit</button>
              <button class="result-delete" @click="deleteAnnotation(index)">Delete</button>
              <button class="result-toggle" @click="toggleAnnotationVisibility(index)">
                {{ annotation.visible ? 'Hide' : 'Show' }}
              </button>
            </div>
          </div>
        </div>
        <div class="history-content">
          <p class="title">History</p>
          <div class="history-group">
            <div 
              v-for="(action, index) in history" 
              :key="index"
              class="history-item"
            >
              <div class="history-action">
                <span class="history-type">{{ action.type }}</span>
                <span v-if="action.label" class="history-label">: {{ action.label }}</span>
              </div>
              <div class="history-time">{{ formatTime(action.timestamp) }}</div>
            </div>
            <div v-if="history.length === 0" class="history-empty">
              No actions yet
            </div>
          </div>
        </div>
        <div class="tab-btn focus" @click="toggleResultPanel">
          <span class="icon-double-angle-right"></span>
        </div>
      </div>

      <!-- Label Manager -->
      <div v-if="showLabelManager" class="label-manage">
        <div class="label-manage-info">
          <div class="label-manage-menu">
            <div class="label-manage-search">
              <input 
                v-model="labelSearchQuery"
                type="text" 
                class="label-search-input" 
                placeholder="Search labels..."
                @keyup.enter="searchLabels"
              >
            </div>
            <div class="label-manage-create-label">
              <button 
                class="button btn-primary label-manage-create-button"
                @click="showCreateLabel = true"
              >
                Create
              </button>
            </div>
          </div>
          <div class="label-manage-sub-list">Label List:</div>
          <div class="label-manage-group">
            <p v-if="labels.length === 0" class="label-tip">Please create labels first</p>
            <ul class="label-manage-ul">
              <li 
                v-for="(label, index) in filteredLabels" 
                :key="index"
                class="label-item"
                @click="selectLabel(label)"
              >
                <span 
                  class="label-color"
                  :style="{ backgroundColor: label.color }"
                ></span>
                <span class="label-name">{{ label.name }}</span>
                <button class="label-edit" @click.stop="editLabel(index)">Edit</button>
                <button class="label-delete" @click.stop="deleteLabel(index)">Delete</button>
              </li>
            </ul>
          </div>
        </div>
        
        <!-- Create/Edit Label -->
        <div v-if="showCreateLabel" class="label-manage-create">
          <div class="label-manage-title">{{ editingLabelIndex >= 0 ? 'Edit' : 'Create' }} Label</div>
          <div class="label-create label-create-name">
            <label>Label Name:</label>
            <input v-model="newLabel.name" type="text" class="label-create-name-input">
          </div>
          <div class="label-create label-create-color">
            <label>Label Color:</label>
            <input 
              v-model="newLabel.color" 
              type="color" 
              class="color-picker"
            >
            <input 
              v-model="newLabel.color" 
              class="color-hex" 
              readonly
            >
          </div>
          <div class="label-create-buttons">
            <button class="button btn-success add-label" @click="saveLabel">Confirm</button>
            <button class="button btn-default close-add" @click="cancelCreateLabel">Cancel</button>
          </div>
        </div>
        
        <div class="close-label-manage" @click="showLabelManager = false">
          <span class="icon-remove-sign">×</span>
        </div>
      </div>
    </div>

    <!-- Mask and Loading -->
    <div v-if="loading" class="mask-box"></div>
    <div v-if="loading" class="loading-box">
      <div class="loader-spinner">
        <span class="icon-spinner">⟳</span>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, onUnmounted, nextTick } from 'vue'

// Types
interface ImageFile {
  name: string
  file: File
  src: string
}

interface Label {
  name: string
  color: string
}

interface Annotation {
  type: 'rect' | 'polygon'
  label: string
  color: string
  visible: boolean
  points: number[]
}

interface HistoryAction {
  type: string
  label: string
  timestamp: number
}

// Reactive data
const canvas = ref<HTMLCanvasElement>()
const fileInput = ref<HTMLInputElement>()
const ctx = ref<CanvasRenderingContext2D>()

// Image cache for smooth rendering
const imageCache = ref<HTMLImageElement | null>(null)
const isImageLoaded = ref(false)

// Animation frame optimization
let animationFrameId: number | null = null
const requestRedraw = () => {
  if (animationFrameId) return
  animationFrameId = requestAnimationFrame(() => {
    redrawCanvas()
    animationFrameId = null
  })
}

const imageList = ref<ImageFile[]>([])
const currentImageIndex = ref(0)
const currentImage = computed(() => imageList.value[currentImageIndex.value] || { name: '', file: null, src: '' })

const showCrosshair = ref(false)
const showAnnotations = ref(true)
const showLabelManager = ref(false)
const showCreateLabel = ref(false)
const loading = ref(false)

const currentTool = ref('drag')
const scale = ref(1)
const imageX = ref(0)
const imageY = ref(0)
const mouseX = ref(0)
const mouseY = ref(0)
const imageWidth = ref(0)
const imageHeight = ref(0)

const annotations = ref<Annotation[]>([])
const labels = ref<Label[]>([
  { name: 'Person', color: '#e74c3c' },
  { name: 'Car', color: '#3498db' },
  { name: 'Building', color: '#2ecc71' },
  { name: 'Animal', color: '#f39c12' },
  { name: 'Object', color: '#9b59b6' }
])
const history = ref<HistoryAction[]>([])

const labelSearchQuery = ref('')
const filteredLabels = computed(() => {
  if (!labelSearchQuery.value) return labels.value
  return labels.value.filter(label => 
    label.name.toLowerCase().includes(labelSearchQuery.value.toLowerCase())
  )
})

const newLabel = reactive({
  name: '',
  color: '#ff0000'
})

const editingLabelIndex = ref(-1)

// Drawing state
const isDrawing = ref(false)
const isDragging = ref(false)
const currentDrawing = ref<number[]>([])
const selectedLabel = ref<Label | null>(labels.value[0])
const startDrawPoint = ref<{x: number, y: number} | null>(null)

// Canvas setup and default images
onMounted(async () => {
  if (canvas.value) {
    ctx.value = canvas.value.getContext('2d')!
    resizeCanvas()
    window.addEventListener('resize', resizeCanvas)
    window.addEventListener('keydown', handleKeyDown)
    
    // Load default sample images
    await loadDefaultImages()
  }
})

onUnmounted(() => {
  window.removeEventListener('resize', resizeCanvas)
  window.removeEventListener('keydown', handleKeyDown)
  
  // Clean up animation frame
  if (animationFrameId) {
    cancelAnimationFrame(animationFrameId)
  }
})

// Keyboard shortcuts
const handleKeyDown = (event: KeyboardEvent) => {
  // Ignore if typing in input fields
  if (event.target instanceof HTMLInputElement) return
  
  switch (event.key) {
    case ' ': // Space - toggle between drag and last annotation tool
      event.preventDefault()
      if (currentTool.value === 'drag') {
        setTool('rect') // Default to rectangle tool
      } else {
        setTool('drag')
      }
      break
    case '1':
      event.preventDefault()
      setTool('rect')
      break
    case '2':
      event.preventDefault()
      setTool('polygon')
      break
    case 'c':
    case 'C':
      event.preventDefault()
      showCrosshair.value = !showCrosshair.value
      toggleCrosshair()
      break
    case 'a':
    case 'A':
      event.preventDefault()
      showAnnotations.value = !showAnnotations.value
      toggleAnnotations()
      break
    case 'f':
    case 'F':
      if (event.ctrlKey || event.metaKey) return // Don't interfere with Ctrl+F
      event.preventDefault()
      toggleFullscreen()
      break
    case 'ArrowLeft':
      event.preventDefault()
      previousImage()
      break
    case 'ArrowRight':
      event.preventDefault()
      nextImage()
      break
    case 'Escape':
      event.preventDefault()
      if (isDrawing.value) {
        // Cancel current drawing
        isDrawing.value = false
        currentDrawing.value = []
        canvas.value!.removeEventListener('mousemove', drawingMouseMove)
        canvas.value!.removeEventListener('mouseup', finishRectDrawing)
        canvas.value!.removeEventListener('dblclick', finishPolygonDrawing)
        redrawCanvas()
        addToHistory('Cancelled Drawing', '')
      }
      if (showLabelManager.value) {
        showLabelManager.value = false
      }
      break
  }
}

// Load default sample images
const loadDefaultImages = async () => {
  const sampleImages = [
    { name: 'band.jpg', url: '/images/band.jpg' },
    { name: 'basketball.jpg', url: '/images/basketball.jpg' },
    { name: 'cat.jpg', url: '/images/cat.jpg' },
    { name: 'dog.jpeg', url: '/images/dog.jpeg' },
    { name: 'dogs.jpg', url: '/images/dogs.jpg' },
    { name: 'football.jpg', url: '/images/football.jpg' },
    { name: 'furniture.jpg', url: '/images/furniture.jpg' },
    { name: 'person.jpg', url: '/images/person.jpg' }
  ]

  for (let i = 0; i < sampleImages.length; i++) {
    const sample = sampleImages[i]
    try {
      // Create a blob URL for the sample image
      const response = await fetch(sample.url)
      if (response.ok) {
        const blob = await response.blob()
        const file = new File([blob], sample.name, { type: blob.type })
        
        imageList.value.push({
          name: sample.name,
          file,
          src: sample.url
        })
      } else {
        console.warn(`Failed to load sample image: ${sample.name} (${response.status})`)
      }
    } catch (error) {
      console.warn(`Failed to load sample image: ${sample.name}`, error)
    }
  }

  if (imageList.value.length > 0) {
    loadImage(0)
  }
}

onUnmounted(() => {
  window.removeEventListener('resize', resizeCanvas)
})

const resizeCanvas = () => {
  if (canvas.value) {
    const container = canvas.value.parentElement!
    canvas.value.width = container.clientWidth
    canvas.value.height = container.clientHeight
    requestRedraw()
  }
}

// Image handling
const openFolder = () => {
  fileInput.value?.click()
}

const handleFileChange = (event: Event) => {
  const files = (event.target as HTMLInputElement).files
  if (files) {
    imageList.value = []
    Array.from(files).forEach((file, index) => {
      if (file.type.startsWith('image/')) {
        const reader = new FileReader()
        reader.onload = (e) => {
          imageList.value.push({
            name: file.name,
            file,
            src: e.target?.result as string
          })
          if (index === 0) {
            loadImage(0)
          }
        }
        reader.readAsDataURL(file)
      }
    })
  }
}

// History management
const addToHistory = (type: string, label: string) => {
  history.value.unshift({
    type,
    label,
    timestamp: Date.now()
  })
  
  // Keep only last 50 history items
  if (history.value.length > 50) {
    history.value = history.value.slice(0, 50)
  }
}

const loadImage = (index: number) => {
  if (index >= 0 && index < imageList.value.length) {
    currentImageIndex.value = index
    isImageLoaded.value = false
    
    const img = new Image()
    img.onload = () => {
      // Cache the loaded image
      imageCache.value = img
      isImageLoaded.value = true
      
      imageWidth.value = img.width
      imageHeight.value = img.height
      
      // Calculate initial scale to fit image in canvas
      const canvasWidth = canvas.value!.width
      const canvasHeight = canvas.value!.height
      const scaleX = canvasWidth / img.width
      const scaleY = canvasHeight / img.height
      scale.value = Math.min(scaleX, scaleY, 1) * 0.8 // 80% to leave some margin
      
      // Center the image
      imageX.value = (canvasWidth - img.width * scale.value) / 2
      imageY.value = (canvasHeight - img.height * scale.value) / 2
      
      // Clear annotations for new image
      annotations.value = []
      
      // Add to history
      addToHistory('Image Loaded', imageList.value[index].name)
      
      redrawCanvas()
    }
    img.onerror = () => {
      console.error('Failed to load image:', imageList.value[index].name)
      isImageLoaded.value = false
      imageCache.value = null
    }
    img.src = imageList.value[index].src
  }
}

const previousImage = () => {
  if (currentImageIndex.value > 0) {
    loadImage(currentImageIndex.value - 1)
  }
}

const nextImage = () => {
  if (currentImageIndex.value < imageList.value.length - 1) {
    loadImage(currentImageIndex.value + 1)
  }
}

// Tool handling
const setTool = (tool: string) => {
  currentTool.value = tool
}

// Canvas events
const canvasMouseDown = (event: MouseEvent) => {
  const rect = canvas.value!.getBoundingClientRect()
  mouseX.value = event.clientX - rect.left
  mouseY.value = event.clientY - rect.top

  if (currentTool.value === 'rect' && selectedLabel.value) {
    isDrawing.value = true
    startDrawPoint.value = { x: mouseX.value, y: mouseY.value }
    currentDrawing.value = [mouseX.value, mouseY.value]
    
    // Add event listener for mouse move during drawing
    canvas.value!.addEventListener('mousemove', drawingMouseMove)
    canvas.value!.addEventListener('mouseup', finishRectDrawing)
    
  } else if (currentTool.value === 'polygon' && selectedLabel.value) {
    if (!isDrawing.value) {
      isDrawing.value = true
      currentDrawing.value = [mouseX.value, mouseY.value]
      canvas.value!.addEventListener('mousemove', drawingMouseMove)
      canvas.value!.addEventListener('dblclick', finishPolygonDrawing)
    } else {
      // Add point to polygon
      currentDrawing.value.push(mouseX.value, mouseY.value)
    }
    redrawCanvas()
    
  } else if (currentTool.value === 'drag') {
    isDragging.value = true
    startDrawPoint.value = { x: mouseX.value, y: mouseY.value }
  }
}

const drawingMouseMove = (event: MouseEvent) => {
  const rect = canvas.value!.getBoundingClientRect()
  mouseX.value = event.clientX - rect.left
  mouseY.value = event.clientY - rect.top
  
  if (isDrawing.value) {
    requestRedraw()
  }
}

const finishRectDrawing = () => {
  if (isDrawing.value && startDrawPoint.value && selectedLabel.value) {
    const width = Math.abs(mouseX.value - startDrawPoint.value.x)
    const height = Math.abs(mouseY.value - startDrawPoint.value.y)
    
    // Only create annotation if rectangle is large enough
    if (width > 10 && height > 10) {
      const x1 = Math.min(startDrawPoint.value.x, mouseX.value)
      const y1 = Math.min(startDrawPoint.value.y, mouseY.value)
      const x2 = Math.max(startDrawPoint.value.x, mouseX.value)
      const y2 = Math.max(startDrawPoint.value.y, mouseY.value)
      
      const annotation: Annotation = {
        type: 'rect',
        label: selectedLabel.value.name,
        color: selectedLabel.value.color,
        visible: true,
        points: [x1, y1, x2, y2]
      }
      
      annotations.value.push(annotation)
      addToHistory('Created Rectangle', selectedLabel.value.name)
    }
  }
  
  // Clean up
  isDrawing.value = false
  currentDrawing.value = []
  startDrawPoint.value = null
  canvas.value!.removeEventListener('mousemove', drawingMouseMove)
  canvas.value!.removeEventListener('mouseup', finishRectDrawing)
  redrawCanvas()
}

const finishPolygonDrawing = () => {
  if (isDrawing.value && currentDrawing.value.length >= 6 && selectedLabel.value) {
    const annotation: Annotation = {
      type: 'polygon',
      label: selectedLabel.value.name,
      color: selectedLabel.value.color,
      visible: true,
      points: [...currentDrawing.value]
    }
    
    annotations.value.push(annotation)
    addToHistory('Created Polygon', selectedLabel.value.name)
  }
  
  // Clean up
  isDrawing.value = false
  currentDrawing.value = []
  canvas.value!.removeEventListener('mousemove', drawingMouseMove)
  canvas.value!.removeEventListener('dblclick', finishPolygonDrawing)
  redrawCanvas()
}

const canvasMouseMove = (event: MouseEvent) => {
  const rect = canvas.value!.getBoundingClientRect()
  mouseX.value = event.clientX - rect.left
  mouseY.value = event.clientY - rect.top

  if (isDragging.value && startDrawPoint.value) {
    // Handle image dragging
    const deltaX = mouseX.value - startDrawPoint.value.x
    const deltaY = mouseY.value - startDrawPoint.value.y
    imageX.value += deltaX
    imageY.value += deltaY
    startDrawPoint.value = { x: mouseX.value, y: mouseY.value }
    requestRedraw()
  } else if (showCrosshair.value) {
    requestRedraw()
  }
}

const canvasMouseUp = () => {
  // Only handle drag operations, don't interfere with drawing operations
  if (currentTool.value === 'drag') {
    isDragging.value = false
    startDrawPoint.value = null
  }
}

const canvasWheel = (event: WheelEvent) => {
  event.preventDefault()
  const delta = event.deltaY > 0 ? 0.9 : 1.1
  const newScale = Math.max(0.1, Math.min(5, scale.value * delta))
  
  // Scale around mouse position
  const mouseCanvasX = mouseX.value
  const mouseCanvasY = mouseY.value
  
  imageX.value = mouseCanvasX - (mouseCanvasX - imageX.value) * (newScale / scale.value)
  imageY.value = mouseCanvasY - (mouseCanvasY - imageY.value) * (newScale / scale.value)
  
  scale.value = newScale
  requestRedraw()
}

// Drawing functions
const redrawCanvas = () => {
  if (!ctx.value || !canvas.value) return

  ctx.value.clearRect(0, 0, canvas.value.width, canvas.value.height)

  // Draw background
  ctx.value.fillStyle = '#f8f9fa'
  ctx.value.fillRect(0, 0, canvas.value.width, canvas.value.height)

  // Draw image using cached image
  if (imageCache.value && isImageLoaded.value) {
    ctx.value.drawImage(
      imageCache.value,
      imageX.value,
      imageY.value,
      imageWidth.value * scale.value,
      imageHeight.value * scale.value
    )
    
    // Draw annotations
    if (showAnnotations.value) {
      drawAnnotations()
    }
    
    // Draw current drawing
    if (isDrawing.value) {
      drawCurrentDrawing()
    }
    
    // Draw crosshair
    if (showCrosshair.value) {
      drawCrosshair()
    }
  } else {
    // Draw crosshair even without image
    if (showCrosshair.value) {
      drawCrosshair()
    }
  }
}

const drawAnnotations = () => {
  annotations.value.forEach((annotation, index) => {
    if (!annotation.visible) return
    
    ctx.value!.strokeStyle = annotation.color
    ctx.value!.lineWidth = 2
    ctx.value!.setLineDash([])
    
    if (annotation.type === 'rect' && annotation.points.length >= 4) {
      const [x1, y1, x2, y2] = annotation.points
      
      // Draw rectangle
      ctx.value!.beginPath()
      ctx.value!.rect(x1, y1, x2 - x1, y2 - y1)
      ctx.value!.stroke()
      
      // Draw semi-transparent fill
      ctx.value!.fillStyle = annotation.color + '20'
      ctx.value!.fill()
      
      // Draw label
      ctx.value!.fillStyle = annotation.color
      ctx.value!.font = '12px Arial'
      const labelWidth = ctx.value!.measureText(annotation.label).width
      const labelX = x1
      const labelY = y1 - 5
      
      // Draw label background
      ctx.value!.fillStyle = annotation.color
      ctx.value!.fillRect(labelX, labelY - 15, labelWidth + 8, 18)
      
      // Draw label text
      ctx.value!.fillStyle = 'white'
      ctx.value!.fillText(annotation.label, labelX + 4, labelY - 2)
      
    } else if (annotation.type === 'polygon' && annotation.points.length >= 6) {
      ctx.value!.beginPath()
      ctx.value!.moveTo(annotation.points[0], annotation.points[1])
      
      for (let i = 2; i < annotation.points.length; i += 2) {
        ctx.value!.lineTo(annotation.points[i], annotation.points[i + 1])
      }
      ctx.value!.closePath()
      ctx.value!.stroke()
      
      // Draw semi-transparent fill
      ctx.value!.fillStyle = annotation.color + '20'
      ctx.value!.fill()
      
      // Draw vertices
      for (let i = 0; i < annotation.points.length; i += 2) {
        ctx.value!.beginPath()
        ctx.value!.arc(annotation.points[i], annotation.points[i + 1], 4, 0, 2 * Math.PI)
        ctx.value!.fillStyle = annotation.color
        ctx.value!.fill()
      }
      
      // Draw label
      ctx.value!.fillStyle = annotation.color
      ctx.value!.font = '12px Arial'
      const labelWidth = ctx.value!.measureText(annotation.label).width
      const labelX = annotation.points[0]
      const labelY = annotation.points[1] - 5
      
      // Draw label background
      ctx.value!.fillStyle = annotation.color
      ctx.value!.fillRect(labelX, labelY - 15, labelWidth + 8, 18)
      
      // Draw label text
      ctx.value!.fillStyle = 'white'
      ctx.value!.fillText(annotation.label, labelX + 4, labelY - 2)
    }
  })
}

const drawCurrentDrawing = () => {
  if (!selectedLabel.value) return
  
  ctx.value!.strokeStyle = selectedLabel.value.color
  ctx.value!.lineWidth = 2
  ctx.value!.setLineDash([5, 5])
  
  if (currentTool.value === 'rect' && startDrawPoint.value) {
    const width = mouseX.value - startDrawPoint.value.x
    const height = mouseY.value - startDrawPoint.value.y
    
    ctx.value!.beginPath()
    ctx.value!.rect(startDrawPoint.value.x, startDrawPoint.value.y, width, height)
    ctx.value!.stroke()
    
    // Draw semi-transparent preview
    ctx.value!.fillStyle = selectedLabel.value.color + '20'
    ctx.value!.fill()
    
  } else if (currentTool.value === 'polygon' && currentDrawing.value.length >= 2) {
    ctx.value!.beginPath()
    ctx.value!.moveTo(currentDrawing.value[0], currentDrawing.value[1])
    
    for (let i = 2; i < currentDrawing.value.length; i += 2) {
      ctx.value!.lineTo(currentDrawing.value[i], currentDrawing.value[i + 1])
    }
    
    // Draw line to current mouse position
    if (currentDrawing.value.length > 2) {
      ctx.value!.lineTo(mouseX.value, mouseY.value)
    }
    
    ctx.value!.stroke()
    
    // Draw vertices
    for (let i = 0; i < currentDrawing.value.length; i += 2) {
      ctx.value!.beginPath()
      ctx.value!.arc(currentDrawing.value[i], currentDrawing.value[i + 1], 4, 0, 2 * Math.PI)
      ctx.value!.fillStyle = selectedLabel.value.color
      ctx.value!.fill()
    }
  }
}

const drawCrosshair = () => {
  ctx.value!.strokeStyle = '#ff0000'
  ctx.value!.lineWidth = 1
  ctx.value!.setLineDash([3, 3])
  ctx.value!.beginPath()
  ctx.value!.moveTo(mouseX.value, 0)
  ctx.value!.lineTo(mouseX.value, canvas.value!.height)
  ctx.value!.moveTo(0, mouseY.value)
  ctx.value!.lineTo(canvas.value!.width, mouseY.value)
  ctx.value!.stroke()
}

// Annotation management
const editAnnotation = (index: number) => {
  // TODO: Implement annotation editing UI
  const annotation = annotations.value[index]
  console.log('Edit annotation', annotation)
  addToHistory('Edit Attempt', annotation.label)
}

const deleteAnnotation = (index: number) => {
  const annotation = annotations.value[index]
  annotations.value.splice(index, 1)
  addToHistory('Deleted', annotation.label)
  redrawCanvas()
}

const toggleAnnotationVisibility = (index: number) => {
  const annotation = annotations.value[index]
  annotation.visible = !annotation.visible
  addToHistory(annotation.visible ? 'Showed' : 'Hidden', annotation.label)
  redrawCanvas()
}

// Feature toggles
const toggleCrosshair = () => {
  addToHistory(showCrosshair.value ? 'Enabled Crosshair' : 'Disabled Crosshair', '')
  redrawCanvas()
}

const toggleAnnotations = () => {
  addToHistory(showAnnotations.value ? 'Showed Annotations' : 'Hidden Annotations', '')
  redrawCanvas()
}

const toggleResultPanel = () => {
  // TODO: Implement panel toggle animation
  console.log('Toggle result panel')
}

const takeScreenshot = () => {
  if (canvas.value) {
    // Create a temporary canvas for clean screenshot
    const tempCanvas = document.createElement('canvas')
    const tempCtx = tempCanvas.getContext('2d')!
    tempCanvas.width = canvas.value.width
    tempCanvas.height = canvas.value.height
    
    // Draw white background
    tempCtx.fillStyle = '#ffffff'
    tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height)
    
    // Draw the current canvas content
    tempCtx.drawImage(canvas.value, 0, 0)
    
    const link = document.createElement('a')
    link.download = `screenshot-${currentImage.value.name}-${Date.now()}.png`
    link.href = tempCanvas.toDataURL('image/png')
    link.click()
    
    addToHistory('Screenshot Taken', currentImage.value.name)
  }
}

const toggleFullscreen = () => {
  if (document.fullscreenElement) {
    document.exitFullscreen()
    addToHistory('Exited Fullscreen', '')
  } else {
    document.documentElement.requestFullscreen()
    addToHistory('Entered Fullscreen', '')
  }
}

const exportJson = () => {
  const data = {
    version: '2.0.0',
    image: {
      name: currentImage.value.name,
      width: imageWidth.value,
      height: imageHeight.value
    },
    annotations: annotations.value.map(ann => ({
      ...ann,
      // Convert screen coordinates to image coordinates
      points: ann.points.map((coord, i) => {
        if (i % 2 === 0) {
          // X coordinate
          return Math.round((coord - imageX.value) / scale.value)
        } else {
          // Y coordinate
          return Math.round((coord - imageY.value) / scale.value)
        }
      })
    })),
    labels: labels.value,
    metadata: {
      created: new Date().toISOString(),
      scale: scale.value,
      imagePosition: {
        x: imageX.value,
        y: imageY.value
      }
    }
  }
  
  const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' })
  const url = URL.createObjectURL(blob)
  const link = document.createElement('a')
  link.href = url
  link.download = `annotations-${currentImage.value.name.replace(/\.[^/.]+$/, '')}-${Date.now()}.json`
  link.click()
  URL.revokeObjectURL(url)
  
  addToHistory('Exported JSON', `${annotations.value.length} annotations`)
}

const searchLabels = () => {
  // Search is handled by computed property
  addToHistory('Searched Labels', labelSearchQuery.value)
}

// Label management
const selectLabel = (label: Label) => {
  selectedLabel.value = label
  showLabelManager.value = false
  addToHistory('Selected Label', label.name)
}

const saveLabel = () => {
  if (!newLabel.name.trim()) return
  
  if (editingLabelIndex.value >= 0) {
    const oldName = labels.value[editingLabelIndex.value].name
    labels.value[editingLabelIndex.value] = { ...newLabel }
    addToHistory('Updated Label', `${oldName} → ${newLabel.name}`)
  } else {
    labels.value.push({ ...newLabel })
    addToHistory('Created Label', newLabel.name)
  }
  
  cancelCreateLabel()
}

const editLabel = (index: number) => {
  editingLabelIndex.value = index
  newLabel.name = labels.value[index].name
  newLabel.color = labels.value[index].color
  showCreateLabel.value = true
}

const deleteLabel = (index: number) => {
  const labelName = labels.value[index].name
  labels.value.splice(index, 1)
  addToHistory('Deleted Label', labelName)
  
  // If deleted label was selected, clear selection
  if (selectedLabel.value?.name === labelName) {
    selectedLabel.value = labels.value.length > 0 ? labels.value[0] : null
  }
}

const cancelCreateLabel = () => {
  showCreateLabel.value = false
  editingLabelIndex.value = -1
  newLabel.name = ''
  newLabel.color = '#ff0000'
}

// Utility functions
const formatTime = (timestamp: number) => {
  const date = new Date(timestamp)
  return date.toLocaleTimeString('en-US', { 
    hour: '2-digit', 
    minute: '2-digit', 
    second: '2-digit' 
  })
}
</script>

<style scoped>
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.image-annotator {
  height: 100vh;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  background: #f5f5f5;
  overflow: hidden;
}

/* Header Styles */
.tool-head {
  background: #2c3e50;
  color: white;
  height: 60px;
  border-bottom: 1px solid #34495e;
}

.tool-muster {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 100%;
  padding: 0 20px;
}

.logo-group {
  display: flex;
  align-items: center;
  gap: 12px;
}

.logo {
  width: 32px;
  height: 32px;
  background: #3498db;
  border-radius: 6px;
  position: relative;
}

.logo::after {
  content: '🖼️';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 16px;
}

.logo-title {
  font-size: 20px;
  font-weight: 600;
}

.page-control {
  display: flex;
  align-items: center;
  gap: 16px;
}

.page-switch {
  width: 32px;
  height: 32px;
  border: 1px solid #bdc3c7;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
}

.page-switch:hover {
  background: #34495e;
  border-color: #3498db;
}

.page-prev::after {
  content: '‹';
  font-size: 18px;
}

.page-next::after {
  content: '›';
  font-size: 18px;
}

.page-info {
  text-align: center;
}

.page-name {
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 2px;
  max-width: 200px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.name-process {
  font-size: 12px;
  opacity: 0.8;
}

.general-features {
  display: flex;
  gap: 24px;
}

.feature-list {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 8px 12px;
  border-radius: 4px;
  transition: background 0.2s;
  font-size: 14px;
}

.feature-list:hover {
  background: rgba(255, 255, 255, 0.1);
}

.mui-switch {
  width: 40px;
  height: 20px;
  background: #bdc3c7;
  border-radius: 10px;
  position: relative;
  cursor: pointer;
  transition: background 0.3s;
}

.mui-switch:checked {
  background: #3498db;
}

.mui-switch::after {
  content: '';
  position: absolute;
  width: 16px;
  height: 16px;
  background: white;
  border-radius: 50%;
  top: 2px;
  left: 2px;
  transition: left 0.3s;
}

.mui-switch:checked::after {
  left: 22px;
}

/* Main Canvas Area */
.canvas-main {
  display: flex;
  height: calc(100vh - 60px);
}

.tool-features {
  width: 80px;
  background: #34495e;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 0;
  gap: 20px;
}

.assist-features {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.open-folder,
.save-json {
  width: 40px;
  height: 40px;
  border: 1px solid #bdc3c7;
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  color: #bdc3c7;
}

.open-folder:hover,
.save-json:hover {
  background: #3498db;
  border-color: #3498db;
  color: white;
}

.open-folder::after {
  content: '📁';
  font-size: 18px;
}

.save-json::after {
  content: '💾';
  font-size: 18px;
}

.separator {
  width: 60%;
  height: 1px;
  background: #4a5f7a;
}

.tools {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.tool-set {
  width: 40px;
  height: 40px;
  border: 1px solid #bdc3c7;
  border-radius: 6px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.2s;
  color: #bdc3c7;
  position: relative;
}

.tool-set:hover,
.tool-set.focus {
  background: #3498db;
  border-color: #3498db;
  color: white;
}

.tool-drag::after {
  content: '✋';
  font-size: 16px;
}

.tool-rect::after {
  content: '⬜';
  font-size: 16px;
}

.tool-polygon::after {
  content: '🔷';
  font-size: 16px;
}

.tool-tags-manager::after {
  content: '🏷️';
  font-size: 16px;
}

.version {
  position: absolute;
  bottom: 20px;
  font-size: 10px;
  color: #bdc3c7;
}

/* Canvas Content */
.canvas-content {
  flex: 1;
  position: relative;
  background: #ecf0f1;
}

#canvas {
  width: 100%;
  height: 100%;
  cursor: crosshair;
}

.scale-box {
  position: absolute;
  bottom: 20px;
  right: 20px;
  background: rgba(0, 0, 0, 0.7);
  color: white;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 12px;
}

/* Results Panel */
.comment-result {
  width: 300px;
  background: white;
  border-left: 1px solid #bdc3c7;
  display: flex;
  flex-direction: column;
  position: relative;
}

.result-area {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
}

.title {
  font-size: 16px;
  font-weight: 600;
  margin-bottom: 16px;
  color: #2c3e50;
}

.result-list-head {
  border-bottom: 1px solid #ecf0f1;
  margin-bottom: 12px;
}

.head-children {
  display: grid;
  grid-template-columns: 1fr 50px 50px 60px;
  gap: 8px;
  padding: 8px 0;
  font-size: 12px;
  font-weight: 600;
  color: #7f8c8d;
}

.result-item {
  display: grid;
  grid-template-columns: 1fr 50px 50px 60px;
  gap: 8px;
  padding: 8px 0;
  border-bottom: 1px solid #ecf0f1;
  align-items: center;
}

.result-name {
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.result-edit,
.result-delete,
.result-toggle {
  background: none;
  border: 1px solid #bdc3c7;
  border-radius: 3px;
  padding: 4px 8px;
  font-size: 10px;
  cursor: pointer;
  transition: all 0.2s;
}

.result-edit:hover {
  background: #3498db;
  color: white;
  border-color: #3498db;
}

.result-delete:hover {
  background: #e74c3c;
  color: white;
  border-color: #e74c3c;
}

.result-toggle:hover {
  background: #f39c12;
  color: white;
  border-color: #f39c12;
}

.history-content {
  border-top: 1px solid #ecf0f1;
  padding: 20px;
  max-height: 200px;
  overflow-y: auto;
}

.history-item {
  padding: 8px 0;
  font-size: 12px;
  color: #7f8c8d;
  border-bottom: 1px solid #ecf0f1;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.history-action {
  flex: 1;
  margin-right: 8px;
}

.history-type {
  font-weight: 600;
  color: #2c3e50;
}

.history-label {
  color: #7f8c8d;
}

.history-time {
  font-size: 10px;
  color: #95a5a6;
  white-space: nowrap;
}

.history-empty {
  text-align: center;
  color: #95a5a6;
  font-style: italic;
  padding: 20px;
}

.tab-btn {
  position: absolute;
  left: -20px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 60px;
  background: #34495e;
  color: white;
  border-radius: 4px 0 0 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.2s;
}

.tab-btn:hover {
  background: #2c3e50;
}

/* Label Manager */
.label-manage {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 500px;
  max-height: 600px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  z-index: 1000;
  display: flex;
}

.label-manage-info {
  flex: 1;
  padding: 24px;
}

.label-manage-menu {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
  align-items: center;
}

.label-search-input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #bdc3c7;
  border-radius: 4px;
  font-size: 14px;
}

.label-manage-create-button {
  background: #3498db;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  transition: background 0.2s;
}

.label-manage-create-button:hover {
  background: #2980b9;
}

.label-manage-sub-list {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 12px;
  color: #2c3e50;
}

.label-manage-group {
  max-height: 300px;
  overflow-y: auto;
}

.label-tip {
  text-align: center;
  color: #95a5a6;
  font-style: italic;
  padding: 20px;
}

.label-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.2s;
}

.label-item:hover {
  background: #ecf0f1;
}

.label-color {
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid white;
  box-shadow: 0 0 0 1px #bdc3c7;
}

.label-name {
  flex: 1;
  font-size: 14px;
}

.label-edit,
.label-delete {
  background: none;
  border: 1px solid #bdc3c7;
  border-radius: 3px;
  padding: 4px 8px;
  font-size: 10px;
  cursor: pointer;
  transition: all 0.2s;
}

.label-edit:hover {
  background: #3498db;
  color: white;
  border-color: #3498db;
}

.label-delete:hover {
  background: #e74c3c;
  color: white;
  border-color: #e74c3c;
}

/* Create Label Panel */
.label-manage-create {
  width: 300px;
  border-left: 1px solid #ecf0f1;
  padding: 24px;
}

.label-manage-title {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 20px;
  color: #2c3e50;
}

.label-create {
  margin-bottom: 16px;
}

.label-create label {
  display: block;
  font-size: 14px;
  font-weight: 500;
  margin-bottom: 6px;
  color: #2c3e50;
}

.label-create-name-input,
.color-hex {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid #bdc3c7;
  border-radius: 4px;
  font-size: 14px;
}

.color-picker {
  width: 40px;
  height: 32px;
  border: 1px solid #bdc3c7;
  border-radius: 4px;
  cursor: pointer;
  margin-right: 8px;
}

.color-hex {
  width: calc(100% - 48px);
  display: inline-block;
}

.label-create-buttons {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}

.button {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s;
}

.btn-success {
  background: #27ae60;
  color: white;
}

.btn-success:hover {
  background: #229954;
}

.btn-default {
  background: #95a5a6;
  color: white;
}

.btn-default:hover {
  background: #7f8c8d;
}

.close-label-manage {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: #e74c3c;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  font-size: 18px;
  transition: background 0.2s;
}

.close-label-manage:hover {
  background: #c0392b;
}

/* Mask and Loading */
.mask-box {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.5);
  z-index: 999;
}

.loading-box {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80px;
  height: 80px;
  background: rgba(0, 0, 0, 0.8);
  border-radius: 8px;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.loader-spinner {
  color: white;
  font-size: 32px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* Responsive */
@media (max-width: 768px) {
  .comment-result {
    width: 250px;
  }
  
  .tool-features {
    width: 60px;
  }
  
  .label-manage {
    width: 90%;
    max-width: 400px;
  }
  
  .label-manage-create {
    width: 100%;
    border-left: none;
    border-top: 1px solid #ecf0f1;
  }
}
</style>
